import re
from rest_framework import serializers
from rest_framework_jwt.serializers import jwt_encode_handler
from rest_framework_jwt.serializers import jwt_payload_handler
from apps.users.models import User


class UserCreateSerializers(serializers.Serializer):
    # 用户id，read_only=True只允许读取不能修改
    id = serializers.IntegerField(read_only=True)
    # 用户名
    username = serializers.CharField(
        min_length=5,
        max_length=20,
        error_messages={
            'min_length': '用户名不能少于5个字符',
            'max_length': '用户名不能多用20个字符'
        }
    )
    mobile = serializers.CharField()

    # 注册时，不能用中文当作用户名
    def validate_username(self, value):
        """
        对用户名进行合法性检查
        :param value：需验证的用户名
        :return：如果验证通过返回value，否则抛出异常
        """
        # 用户名必须包含字母
        if not re.search(r'[a-zA-Z\d_]', value):
            raise serializers.ValidationError('用户名中必须包含字母')
        # 验证用户名是否存在
        if User.objects.filter(username=value):
            raise serializers.ValidationError('此用户名已存在')
        return value

    def validate_mobile(self, value):
        """
        验证手机号是否合法
        :param value: 需验证的手机号
        ：return； 如果手机号正确返回value, 否则抛出异常
        """
        res = re.search(r'^[1]\d{10}$', value)
        if not res:
            raise serializers.ValidationError('电话号码不匹配')
        return value

    password = serializers.CharField(
        write_only=True,
        min_length=6,
        max_length=20,
        error_messages={
            'min_length': '密码不能少于6个字符',
            'max_length': '密码不能超过20个字符'
        }
    )
    # 密码2.为了校验密码是否一致
    password2 = serializers.CharField(
        write_only=True,
        min_length=6,
        max_length=20,
        # 错误信息
        error_messages={
            'min_length': '密码不能少于6个字符',
            'max_length': '密码不能超过20个字符'
        }
    )

    # 校验两次密码是否一致
    def validate(self, attrs):
        password1 = attrs['password']
        password2 = attrs['password2']
        if password1 != password2:
            raise serializers.ValidationError('密码输入错误')
        return attrs

    # token
    token = serializers.CharField(read_only=True)

    def create(self, data):
        """
        保存数据
        :param data:一个包含用户名、密码等信息的字典
        :return: 返回一个user对象
        """
        user = User()
        user.username = data.get('username')
        user.mobile = data.get('mobile')
        # set_password方法  密码加密
        user.set_password(data.get('password'))
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token
        user.save()
        return user
